﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using MAPDavy.Entities;
using MAPDavy.BusinessLogic;

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using MvcSiteMapProvider;
using MAPDavy.WebMVC3.ViewModels;

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

using System.IO; 

namespace MAPDavy.WebMVC3.Controllers
{
    public class ScoreController : Controller
    {

        public ScoreController()
        {
            using (IUnityContainer container = new UnityContainer())
            {
                container.LoadConfiguration();
                container.BuildUp(this.GetType(), this);
            }
        }

        [Dependency]
        public IScoreBL  ScoreBL { get; set; }

        [Dependency]
        public ITermBL  TermBL { get; set; }

        [Dependency]
        public ISeccionTutorBL  SeccionTutorBL { get; set; }

        [Dependency]
        public ITestBL  TestBL { get; set; }

        [Dependency]
        public IAnioLectivoBL AnioLectivoBL { get; set; }

        [Dependency]
        public IGradeBL GradeBL { get; set; }

        [Dependency]
        public ISeccionBL SeccionBL { get; set; }
        //
        // GET: /Score/

        public ActionResult Index()
        {
            return View();
        }


        //[HttpPost]
        [Authorize]
        public ActionResult GetScoreServiceJson(Int32 termId, Int32 seccionId, Int32 testId)
        {
            var scores = ScoreBL.GetFromScoreByTermIdAndSeccionIdAndTestId(termId, seccionId, testId);

            return Json(scores, JsonRequestBehavior.AllowGet);
        }

        [MvcSiteMapNode(Title = "Registrar RIT", ParentKey = "rit")]
        [Authorize(Roles = "admin,editor")]
        public ActionResult RegistarRit(Int32 termId=0, Int32 seccionId=0)
        {
            var cookie = Request.Cookies["workspace"];

            if (cookie == null)
            {
                return RedirectToAction("Index", "Home");
            }

            if (termId== 0 && seccionId==0)
            {
                return RedirectToAction("Index", "Term");    
            }

            var term = TermBL.GetFromTermById(termId);

            if (term == null)
            {
                return RedirectToAction("Index", "Term");
            }

            if (term.Anio != cookie.Value.ToString())
            {
                return RedirectToAction("Index", "Term");
            }
            //var url = RedirectToAction("ChooseSection", "Term", new { id = term.Id });
            //SiteMap.CurrentNode.ParentNode.Url = url; //"../Term/ChooseSection/" + term.Id.ToString();

            var seccionTutor = SeccionTutorBL.GetFromSeccionTutorRepositorBySeccionIdAndAnio(seccionId, Int32.Parse(term.Anio));  
            
            if (seccionTutor == null)
            {
                return RedirectToAction("Index", "Term");
            }

            var tests = TestBL.GetFromTestByTermIdAndGradeId(termId, seccionTutor.Seccion.GradeId);

            var subjs = from t in tests
                       select new { Id = t.Id, Subject = t.Subject.NameSubject };

            //ViewData["Test"] = new SelectList(tests, "Id", "NameTest");
            ViewData["Test"] = new SelectList(subjs, "Id", "Subject");
            ViewData["GradeId"] = seccionTutor.Seccion.GradeId; 

            var regRitVM = new RegistrarRitViewModel() 
            {
                Term = term,
                SeccionTutor = seccionTutor
            };

            return View(regRitVM);
        }

        [HttpPost]
        [Authorize(Roles = "admin,editor")]
        public ActionResult RegistarRit(Int32 testGradeId, Int32 matriculaId, Int32? rit, Int32 scoreId=0)
        {
            try
            {
                var score = new Score()
                {
                    Id = scoreId,
                    TestGradeId = testGradeId,
                    MatriculaId = matriculaId,
                    RIT = rit,
                    DateTest = DateTime.Now
                };

                ScoreBL.RegistrarScore(score);  

                var result = new 
                { 
                    escoreUP = score,
                    exito = true
                };

                return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (SystemException ex)
            {
                var result = new
                {
                    escoreUP = ex.Message,
                    exito = false
                };

                return Json(result, JsonRequestBehavior.AllowGet);
            }
        }

        public ActionResult LoaderRit(Int32 id = 0)
        {
            var cookie = Request.Cookies["workspace"];

            if (cookie == null)
            {
                return RedirectToAction("Index", "Home");
            }

            if (id == 0)
            {
                return RedirectToAction("Index", "Term");
            }

            var term = TermBL.GetFromTermById(id);

            if (term == null)
            {
                return RedirectToAction("Index", "Term");
            }

            if (term.Anio != cookie.Value.ToString())
            {
                return RedirectToAction("Index", "Term");
            }

            if (term.Cerrado)
            {
                return RedirectToAction("Index", "Term");
            }

            var grades = GradeBL.GetFromGradeByTermId(id);

            var seccions = SeccionBL.GetFromSeccionByGradeId(grades.FirstOrDefault().Id);

            ViewData["grade"] = new SelectList(grades, "Id", "GradeLevel");
            ViewData["seccion"] = new SelectList(seccions, "Id", "ClassName");

            var tests = TestBL.GetFromTestByTermIdAndGradeId(term.Id, grades.FirstOrDefault().Id);

            var subjs = from t in tests
                        select new { Id = t.Id, Subject = t.Subject.NameSubject };

            ViewData["test"] = new SelectList(subjs, "Id", "Subject");

            return View(term);
        }

        [HttpPost]
        [Authorize(Roles = "admin,editor")]
        public ActionResult UploadRit(HttpPostedFileBase userfile)
        {
            var cookie = Request.Cookies["workspace"];

            if (cookie == null)
            {
                return Json(false, JsonRequestBehavior.AllowGet);
            }

            var pathR = Path.Combine(Server.MapPath("~/files/" + cookie.Value.ToString()));

            if (!Directory.Exists(pathR))
            {
                Directory.CreateDirectory(pathR);
            }

            if (userfile != null && userfile.ContentLength > 0)
            {
                var token = Guid.NewGuid().ToString();

                var fileDataName = "LoaderRIT_" + token +Path.GetExtension(userfile.FileName);
                pathR = Path.Combine(pathR, fileDataName);
                userfile.SaveAs(pathR);

                Session["fileDataName"] = fileDataName;
            }

            var msg = new { rpt = true };

            return Json(msg, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        [Authorize(Roles = "admin,editor")]
        public ActionResult ShowLoadData(bool complete = false)
        {
            if (complete)
            {
                var cookie = Request.Cookies["workspace"];

                if (cookie == null)
                {
                    var result = new
                    {
                        mapRit = "",
                        exito = true,
                        msg = "La Sesion ha expirado"
                    };

                    return Json(result, JsonRequestBehavior.AllowGet);
                }

                var pathR = Path.Combine(Server.MapPath("~/files/" + cookie.Value.ToString()));
                var fileDataName = Session["fileDataName"].ToString();
                pathR = Path.Combine(pathR, fileDataName);

                var urlFile = "~/files/" + cookie.Value.ToString() + "/" + fileDataName;

                using (var document = SpreadsheetDocument.Open(pathR, true))
                {
                    try
                    {
                        var workbook = document.WorkbookPart.Workbook;
                        var workSheets = workbook.Descendants<Sheet>();

                        string sheetId = workSheets.First(s => s.Name == @"MapRITTemplate").Id;
                        var sheet = (WorksheetPart)document.WorkbookPart.GetPartById(sheetId);

                        var sharedStringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
                        var mapRit = ScoreBL.RetrieveTemplateRit(sheet.Worksheet, sharedStringTable);

                        var result = new
                        {
                            mapRit = mapRit,
                            exito = true,
                            msg = "",
                            count = mapRit.Count(),
                            urlFile = urlFile
                        };

                        Session["MapRITTemplate"] = mapRit;

                        return Json(result, JsonRequestBehavior.AllowGet);
                    }
                    catch
                    {
                        var result = new
                        {
                            map = "",
                            exito = false,
                            msg = "El documento to tiene el formato correcto."
                        };

                        return Json(result, JsonRequestBehavior.AllowGet);
                    }

                }
            }
            else
            {
                var result = new
                {
                    map = "",
                    exito = false,
                    msg = "El Archivo no ha sido cargado."
                };

                return Json(result, JsonRequestBehavior.AllowGet);
            }
        }

        public ActionResult RegistarRitBach(int termId, int gradeId, int testId)
        {
            if (Session["MapRITTemplate"] == null)
            {
                var error = new
                {
                    afectados = 0,
                    exito = false,
                    msg = "La Sesión a Expirado vuelva a Cargar el archivo."
                };

                return Json(error, JsonRequestBehavior.AllowGet);
            }

            try
            {
                var mapRits = Session["MapRITTemplate"] as List<MAPRit>;
                var rits = ScoreBL.GetFromScoreByTermIdAndGradeIdAndTest(termId, gradeId, testId);

                var query = from mr in mapRits
                            join r in rits on mr.StudentID.Value.ToString() equals r.StudentId  
                            select new Score
                              {
                                  Id = r.ScoreId.HasValue?r.ScoreId.Value:0,
                                  MatriculaId = r.MatriculaId,
                                  TestGradeId = r.TestGradeId,
                                  Locket = false,
                                  DateTest = DateTime.Now,
                                  RIT = mr.RIT
 
                              };

                var scores = query.ToList();

                var query2 = from mr in mapRits
                            join r in rits on mr.StudentID.Value.ToString() equals r.StudentId  
                            select new MAPRit
                              {
                                   StudentID = mr.StudentID,
                                   Student = mr.Student,
                                   Grade = mr.Grade,
                                   RIT = mr.RIT
                              };

                var query3 = from mr in mapRits
                             where !query2.Select(q=>q.StudentID).Contains(mr.StudentID)
                             select mr;

                var not = query3.ToList();

                var afec = ScoreBL.RegistrarScore(scores); 

                var result = new
                {
                    afectados = afec,
                    dirty = not,
                    exito = true,
                    msg = string.Format("Resultados Registrados: {0}", afec)
                };

                return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                string msg = ex.InnerException != null ? ex.InnerException.Message : ex.Message;

                var error = new
                {
                    afectados = 0,
                    exito = false,
                    msg = msg
                };

                return Json(error, JsonRequestBehavior.AllowGet);
            }
        }
    }
}
